﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.IO;

namespace NFinalControllerGenerator
{
    public class GetFieldsUtility
    {
        public static void BuildStruct(TextWriter sw, List<KeyValuePair<string, DeclareData>> declares)
        {
            foreach (var de in declares)
            {
                sw.Write("\t\t");
                sw.Write("public ");
                sw.Write(de.Value.Type);
                sw.Write(" ");
                sw.Write(de.Value.Name);
                if (de.Value.IsAttribute)
                {
                    sw.WriteLine("{get;set;}");
                }
                else
                {
                    sw.WriteLine(";");
                }
            }
        }
        public static void  GetLocalVars(MethodDeclarationSyntax methodT, SemanticModel model, ref Dictionary<string, DeclareData> declares)
        {
            var methodSy = model.GetDeclaredSymbol(methodT);
            ILocalSymbol localSy = null;
            DeclareData data = new DeclareData();
            foreach (var declear in methodT.Body.DescendantNodes().OfType<LocalDeclarationStatementSyntax>())
            {
                foreach (var declearVar in declear.Declaration.Variables)
                {
                    localSy = (ILocalSymbol)model.GetDeclaredSymbol(declearVar);
                    data.IsAttribute = false;
                    data.Type = localSy.Type.ToString();
                    data.Name = localSy.Name;
                    if (!declares.ContainsKey(data.Name))
                    {
                        declares.Add(data.Name, data);
                    }
                }
            }
            foreach (var par in methodSy.Parameters)
            {
                data.IsAttribute = false;
                data.Type = par.Type.ToString();
                data.Name = par.Name;
            }
        }

        public static void GetAllFieldsAndPropertys(INamedTypeSymbol symbol, int level, ref Dictionary<string, DeclareData> declares)
        {
            if (symbol != null)
            {
                DeclareData data = new DeclareData();
                foreach (var filed in symbol.GetMembers().OfType<IFieldSymbol>())
                {
                    if (filed.CanBeReferencedByName)
                    {
                        data.IsAttribute = false;
                        data.Type = filed.Type.ToString();
                        data.Name = filed.Name;
                        if (!declares.ContainsKey(data.Name))
                        {
                            declares.Add(data.Name, data);
                        }
                    }
                }
                foreach (var property in symbol.GetMembers().OfType<IPropertySymbol>())
                {
                    data.IsAttribute = true;
                    data.Type = property.Type.ToString();
                    data.Name = property.Name;
                    if (!declares.ContainsKey(data.Name))
                    {
                        declares.Add(data.Name, data);
                    }
                }
            }
            if (symbol.BaseType != null)
            {
                GetAllFieldsAndPropertys(symbol.BaseType, level, ref declares);
            }
        }
    }
}
